Skip to content

Tunnel inbound: Compatible with listening UNIX domain socket#5693

Merged
RPRX merged 5 commits intoXTLS:mainfrom
smaznet:patch-1
Apr 11, 2026
Merged

Tunnel inbound: Compatible with listening UNIX domain socket#5693
RPRX merged 5 commits intoXTLS:mainfrom
smaznet:patch-1

Conversation

@smaznet
Copy link
Copy Markdown
Contributor

@smaznet smaznet commented Feb 14, 2026

Forward connections from UNIX to TCP network type.

Added support listening on unix socket for dokodemo and forwarding to TCP endpoint

  {
      "listen": "@test.socket",
      "port": 10085,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1",
        "network": "unix",
        "port": 8000
      },
      "tag": "test"
    }

creates a unix listener and forwards incoming request to that unix to tcp addr

   $ curl --abstract-unix-socket test.socket 127.0.0.1
<!DOCTYPE HTML>
<html lang="en">

Forward connections from UNIX to TCP network type.
@Fangliding
Copy link
Copy Markdown
Member

?

@Fangliding Fangliding closed this Feb 14, 2026
@smaznet
Copy link
Copy Markdown
Contributor Author

smaznet commented Feb 14, 2026

Why?

@Fangliding
Copy link
Copy Markdown
Member

Fangliding commented Feb 14, 2026

Sorry, I remembered sth incorrectly

@Fangliding Fangliding reopened this Feb 14, 2026
@RPRX
Copy link
Copy Markdown
Member

RPRX commented Feb 21, 2026

"network": "unix",

配置示例里这个?

@smaznet
Copy link
Copy Markdown
Contributor Author

smaznet commented Feb 21, 2026

yes

@smaznet
Copy link
Copy Markdown
Contributor Author

smaznet commented Feb 21, 2026

actually it listens on unix on client but sends to that tcp address better to rename it unix-tcp but this works for now

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Feb 21, 2026

哦哦 address 和 port 是 target,然而这个 network 是 listen 的 network,感觉需要一些 rename 不然有点混乱

另外这个 network 应该放外面然后改成 "udp": "enabled"/"only" 才对,而不是根据 settings/streamSettings 来自动判断?

@Fangliding
Copy link
Copy Markdown
Member

Fangliding commented Feb 21, 2026

这一改现有配置又要大炸特炸了 这个需求很小众我觉得这个PR这么改几行就行了
还是core里一些部分把uds封装进TCP逻辑了一部分没有的锅

@smaznet
Copy link
Copy Markdown
Contributor Author

smaznet commented Feb 21, 2026

in previous versions we also can have unix as network and nothing changed i just changed logic to forward to tcp instead of unix as target

append unix as dokodemo network
@smaznet
Copy link
Copy Markdown
Contributor Author

smaznet commented Feb 21, 2026

now this works no need to configure network as unix

    {
      "listen": "@test.socket",
      "port": 10085,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1",
        "network": "tcp",
        "port": 8000
      },
      "tag": "test"
    }

logs:

app/proxyman/inbound: creating unix domain socket worker on @test.socket

if we change listen to 0.0.0.0 it listens on port

 {
      "listen": "0.0.0.0",
      "port": 10085,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1",
        "network": "tcp",
        "port": 8000
      },
      "tag": "test"
    }

logs:

app/proxyman/inbound: creating stream worker on 0.0.0.0:10085

@smaznet
Copy link
Copy Markdown
Contributor Author

smaznet commented Feb 21, 2026

in other word if we have network tcp we can set listen as unix address like vless , trojan, vmess

@smaznet
Copy link
Copy Markdown
Contributor Author

smaznet commented Feb 21, 2026

now unix socket works with udp too

{
      "listen": "@test.socket",
      "port": 10085,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1",
        "network": "udp",
        "port": 8000
      },
      "tag": "test"
    }

@smaznet
Copy link
Copy Markdown
Contributor Author

smaznet commented Feb 21, 2026

Example config for test

{
  "log": {
    "loglevel": "debug"
  },
  "inbounds": [

    {
      "listen": "@test-tcp.socket",
      "port": 10085,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1",
        "network": "tcp",
        "port": 8000 // forward to block-in for test
      },
      "tag": "test-tcp"
    },
    {
      "listen": "@test.socket",
      "port": 10085,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1",
        "network": "udp",
        "port": 8000 // forward to block-in for test
      },
      "tag": "test"
    },
    {
      "listen": "127.0.0.1",
      "port": 8000, // simple tcp,udp server on port 8000
      "tag": "block-in", 
      "protocol": "dokodemo-door",
      "settings": {
        "network": "tcp,udp"
      }
    }

  ],
  "outbounds": [
    {
      "tag": "free",
      "protocol": "freedom"
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {
        "response": {
          "type": "http"
        }
      }
    }
  ],
  "routing": {
    "rules": [
      {
        "inboundTag": [
          "block-in"
        ],
        "outboundTag": "block",
        "type": "field"
      }
    ],
    "domainStrategy": "AsIs"
  }
}

udp test

$ nc -U @test.socket
GET /

Responses:
HTTP/1.1 403 Forbidden
Connection: close
Cache-Control: max-age=3600, public
Content-Length: 0

tcp test

$ nc -U @test-tcp.socket
HTTP/1.1 403 Forbidden
Connection: close
Cache-Control: max-age=3600, public
Content-Length: 0

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Mar 2, 2026

我感觉这个 network 写 unix 第一眼看还是太违和了,要不还是写 tcp/udp/tcp,udp 吧,虽然现在似乎不能监听 UDP UDS

@RPRX RPRX force-pushed the main branch 2 times, most recently from 9529a82 to 2320416 Compare March 22, 2026 13:36
@RPRX
Copy link
Copy Markdown
Member

RPRX commented Mar 22, 2026

看了下代码,network 仍写 tcp 的话 proxy.Inbound interface 取 Network() 会出问题对吧,但是写 unix 的话下面这段?

	// forwarding from unix to tcp add
	if network == net.Network_UNIX {
		network =  d.config.Networks[0]
	}

@Fangliding 你看看

@Fangliding
Copy link
Copy Markdown
Member

slices.Contains 看一眼有没有TCP有就多回一个 UNIX 进去就行了 这里确实不严谨
或者发现没指定port直接开dsworker就行了 always.go 里俩嵌套if判断一遍network有没有UNIX也有点脱裤放屁的感觉

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Mar 29, 2026

@Fangliding 你直接改下这个 PR 吧

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 11, 2026

@Fangliding 我发现现在这 listen 无法同时监听 DS 和 TCP/UDP,而且根据协议来判断 listen 类型 emmm,改成数组更好:

  • / 或 @ 或 @@(不确定要不要加 unix://)
  • tcp://0.0.0.0:10000-10001
  • udp://127.0.0.1:20000-20002

总之现在乱乱的,这个 PR 先这样吧,下个版本重构一下改成入站共用 inbound 实例加支持上面的语法糖,不需要 port 了

@Fangliding
Copy link
Copy Markdown
Member

应该没人需要同时听uds和tcp吧 需要UDS的都是要性能的回环爱好者或者不想占端口 没理由再要个tcp

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 11, 2026

另一个问题:话说它这个 Network() 返回的是“允许监听的网络类型”而不是“必须监听的网络类型”对吧,懒得看代码了

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 11, 2026

额看了下 app/proxyman/inbound/always.go 的代码,就挺不严谨的,应该是配置解析那里把 ds 时的 port 清了吧,懒得翻了

@Fangliding
Copy link
Copy Markdown
Member

另一个问题:话说它这个 Network() 返回的是“允许监听的网络类型”而不是“必须监听的网络类型”对吧,懒得看代码了

有歧义 甚至很史

UDP=我需要监听UDP
TCP=我需要监听TCP
UNIX=我允许监听UNIX

其中 “监听TCP” 意味着监听底层传输 而底层传输实际用的东西可能也是UDP(比如KCP/QUIC)比如当年有ss如果over quic会导致ss自己为了原生UDP监听的UDP端口和QUIC也去监听那个UDP端口然后打架的

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 11, 2026

总之合了这个 PR 后 Tunnel inbound 的行为看代码是:

  • network 留空(配置解析时默认等于 "tcp")或含 "tcp" 时,listen 可以填 IP 或 UDS
  • network 只有 "unix" 或 "udp" 时,listen 只能填 UDS 或 IP
  • 代码里先看 listen,比如填了 IP 就必须填 port,填了 UDS 就会扔掉 port,再看 network底层传输等具体需求
  • 其它组合情况以及非 RAW 底层传输的情况暂不讨论

@RPRX RPRX changed the title Handle UNIX network connections in Process method Tunnel inbound: Compatible with listening UNIX domain socket Apr 11, 2026
@RPRX RPRX merged commit 3293784 into XTLS:main Apr 11, 2026
39 checks passed
@smaznet smaznet deleted the patch-1 branch April 11, 2026 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants